home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_gen / euphor14.zip / MACHINE.E < prev    next >
Text File  |  1996-10-15  |  5KB  |  176 lines

  1.         ----------------------------------------
  2.         -- Machine Level Programming for 386+ --
  3.         ----------------------------------------
  4.  
  5. -- Warning: Some of these routines require a knowledge of 
  6. -- machine-level programming. You could crash your system!
  7.  
  8. -- These routines, along with peek(), poke() and call(), let you access all 
  9. -- of the features of your computer.  You can read and write to any memory 
  10. -- location, and you can create and execute machine code subroutines.
  11.  
  12. -- Writing characters to screen memory with poke() is much faster than  
  13. -- using puts().
  14. -- address of start of text screen memory 
  15. --       mono: #B0000
  16. --      color: #B8000
  17.  
  18. -- see demo\callmach.ex for an example of calling a machine language routine
  19.  
  20. constant M_ALLOC = 16,
  21.      M_FREE = 17,
  22.      M_ALLOC_LOW = 32,
  23.      M_FREE_LOW = 33,
  24.      M_INTERRUPT = 34,
  25.      M_SET_RAND = 35,
  26.      M_USE_VESA = 36,
  27.      M_CRASH_MESSAGE = 37
  28.      
  29. -- biggest address on a 32-bit machine
  30. constant MAX_ADDR = power(2, 32)-1
  31.  
  32. -- biggest address accessible to 16-bit real mode
  33. constant LOW_ADDR = power(2, 20)-1
  34.  
  35. type machine_addr(atom a)
  36. -- a legal machine address 
  37.     return a > 0 and a <= MAX_ADDR and floor(a) = a
  38. end type
  39.  
  40. type low_machine_addr(atom a)
  41. -- a legal low machine address 
  42.     return a > 0 and a <= LOW_ADDR and floor(a) = a
  43. end type
  44.  
  45. global constant REG_LIST_SIZE = 10
  46. global constant REG_DI = 1,      
  47.         REG_SI = 2,
  48.         REG_BP = 3,
  49.         REG_BX = 4,
  50.         REG_DX = 5,
  51.         REG_CX = 6,
  52.         REG_AX = 7,
  53.         REG_FLAGS = 8, -- on input: ignored 
  54.                    -- on output: low bit has carry flag for 
  55.                    -- success/fail
  56.         REG_ES = 9,
  57.         REG_DS = 10
  58.  
  59. type register_list(sequence r)
  60. -- a list of register values
  61.     return length(r) = REG_LIST_SIZE
  62. end type
  63.  
  64. global function allocate(integer n)
  65. -- Allocate n bytes of memory and return the address.
  66. -- Free the memory using free() below.
  67.     return machine_func(M_ALLOC, n)
  68. end function
  69.  
  70. global procedure free(machine_addr a)
  71. -- free the memory at address a
  72.     machine_proc(M_FREE, a)
  73. end procedure
  74.  
  75. global function allocate_low(integer n)
  76. -- Allocate n bytes of low memory (address less than 1Mb) 
  77. -- and return the address. Free this memory using free_low() below.
  78. -- Addresses in this range can be passed to DOS during software interrupts.
  79.     return machine_func(M_ALLOC_LOW, n)
  80. end function
  81.  
  82. global procedure free_low(low_machine_addr a)
  83. -- free the low memory at address a
  84.     machine_proc(M_FREE_LOW, a)
  85. end procedure
  86.  
  87. global function dos_interrupt(integer int_no, register_list input_regs)
  88. -- call the DOS operating system via software interrupt int_no, using the
  89. -- register values in input_regs. A similar register_list is returned.
  90. -- It contains the register values after the interrupt.
  91.     return machine_func(M_INTERRUPT, {int_no, input_regs})
  92. end function
  93.  
  94. global function int_to_bytes(atom x)
  95. -- returns value of x as a sequence of 4 bytes 
  96. -- that you can poke into memory 
  97. --      {bits 0-7,  (least significant)
  98. --       bits 8-15,
  99. --       bits 16-23,
  100. --       bits 24-31} (most significant)
  101. -- This is the order of bytes in memory on 386+ machines.
  102.     integer a,b,c,d
  103.     
  104.     a = remainder(x, #100)
  105.     x = floor(x / #100)
  106.     b = remainder(x, #100)
  107.     x = floor(x / #100)
  108.     c = remainder(x, #100)
  109.     x = floor(x / #100)
  110.     d = remainder(x, #100)
  111.     return {a,b,c,d}
  112. end function
  113.  
  114. global function bytes_to_int(sequence s)
  115. -- converts 4-byte peek() sequence into an integer value
  116.     return s[1] + 
  117.        s[2] * #100 + 
  118.        s[3] * #10000 + 
  119.        s[4] * #1000000
  120. end function
  121.  
  122. global function int_to_bits(atom x, integer nbits)
  123. -- Returns the low-order nbits bits of x as a sequence of 1's and 0's. 
  124. -- Note that the least significant bits come first. You can use Euphoria's
  125. -- and/or/not operators on sequences of bits. You can also subscript, 
  126. -- slice, concatenate etc. to manipulate bits.
  127.     sequence bits
  128.     
  129.     if x < 0 then
  130.     x = x + power(2, nbits) -- provide 2's complement bit pattern
  131.     end if
  132.     bits = repeat(0, nbits)
  133.     for i = 1 to nbits do
  134.     bits[i] = remainder(x, 2) 
  135.     x = floor(x / 2)
  136.     end for
  137.     return bits
  138. end function
  139.  
  140. global function bits_to_int(sequence bits)
  141. -- get the (positive) value of a sequence of "bits"
  142.     atom value, p
  143.     
  144.     value = 0
  145.     p = 1
  146.     for i = 1 to length(bits) do
  147.     if bits[i] then
  148.         value = value + p
  149.     end if
  150.     p = p + p
  151.     end for
  152.     return value
  153. end function
  154.  
  155. global procedure set_rand(integer seed)
  156. -- reset the random number generator 
  157. -- A given value of seed will cause the same series of
  158. -- random numbers to be generated from the rand() function
  159.     machine_proc(M_SET_RAND, seed)
  160. end procedure
  161.  
  162. global procedure use_vesa(integer code)
  163. -- If code is 1 then force Euphoria to use the VESA graphics standard.
  164. -- This may let Euphoria work better in SVGA modes with certain graphics cards.
  165. -- If code is 0 then Euphoria's normal use of the graphics card is restored.
  166. -- Values of code other than 0 or 1 should not be used.
  167.     machine_proc(M_USE_VESA, code)
  168. end procedure
  169.  
  170. global procedure crash_message(sequence msg)
  171. -- Specify a final message to display for your user, in the event 
  172. -- that Euphoria has to shut down your program due to an error.
  173.     machine_proc(M_CRASH_MESSAGE, msg)
  174. end procedure
  175.  
  176.